package tcp

import (
	"JoRedis/constant"
	"JoRedis/interface/tcp"
	"JoRedis/lib/logger"
	"context"
	"net"
	"os"
	"os/signal"
	"sync"
	"syscall"
)

type HandlerFun func(ctx context.Context, conn net.Conn)

type ServerConfig struct {
	NetAddr string
}

// ListenAndServer 监听Tcp和启动服务处理程序
func ListenAndServer(serverConfig *ServerConfig, serverHandler tcp.ServerHandlerItf) error {
	closeServerChn := make(chan struct{})
	quitChn := make(chan os.Signal)
	signal.Notify(quitChn, syscall.SIGHUP, syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGINT, syscall.SIGKILL)
	// 监听程序的终止
	go func() {
		<-quitChn
		logger.Info(constant.SERVER_LOG_TIP + "Exit!")
		closeServerChn <- struct{}{}
	}()

	// 启动tcp监听
	listener, err := net.Listen("tcp", serverConfig.NetAddr)
	if err != nil {
		return err
	}
	defer func() {
		_ = listener.Close()
		_ = serverHandler.CloseAll()
	}()

	logger.Info(constant.SERVER_LOG_TIP + "开始监听")

	go func() {
		<-closeServerChn
		_ = listener.Close()
		logger.Info(constant.SERVER_LOG_TIP + "关闭Tcp连接监听!")
		// 释放所有的客户端连接
		_ = serverHandler.CloseAll()
		logger.Info(constant.SERVER_LOG_TIP + "客户端连接释放完毕!")
	}()

	var wt sync.WaitGroup
	for {
		// 等待tcp连接
		clientConn, err := listener.Accept()
		if err != nil {
			break
		}

		logger.Info("接收新的客户端连接:" + clientConn.RemoteAddr().String())

		ctx := context.Background()
		wt.Add(1)
		go func() {
			defer wt.Done()
			serverHandler.Handle(ctx, clientConn)
		}()
	}
	// 等待所有客户端处理完
	wt.Wait()
	return nil
}
